package com.cn.demo.springboot.shiro.service.impl;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.cn.demo.springboot.shiro.annotation.BodyPermissions;
import com.cn.demo.springboot.shiro.annotation.MenuEx;
import com.cn.demo.springboot.shiro.config.AuthRealm;
import com.cn.demo.springboot.shiro.entity.Menu;
import com.cn.demo.springboot.shiro.entity.Permission;
import com.cn.demo.springboot.shiro.entity.Role;
import com.cn.demo.springboot.shiro.entity.ShiroUser;
import com.cn.demo.springboot.shiro.mapper.MenuMapper;
import com.cn.demo.springboot.shiro.mapper.PermissionMapper;
import com.cn.demo.springboot.shiro.mapper.RoleMapper;
import com.cn.demo.springboot.shiro.mapper.ShiroMapper;
import com.cn.demo.springboot.shiro.service.IAuthRealmService;
@Service
@Transactional
public class AuthRealmServiceImpl implements IAuthRealmService {
	@Autowired
	private ShiroMapper shiroMapper;
	
	@Override
	public ShiroUser findUserByAccount(String account) {
		return shiroMapper.findUserByAccount(account);
	}

	@Override
	public Set<String> getPermissions(String userId) {
		return shiroMapper.getPermissions(userId);
	}
	
	/**************************************初始化菜单和权限--start**************************************/

	@Autowired
	private ApplicationContext applicationContext;
	
	@Autowired
	private  MenuMapper menuMapper;
	
	@Autowired
	private  PermissionMapper permissionMapper;

	/**
	 * 初始化菜单和权限
	 */
	//@PostConstruct
	@Transactional
	protected void initMenuAndPermissions() {

		// 内容请求集合
		List<BodyPermissions> bodyPermissionsList = new ArrayList<BodyPermissions>();

		// 菜单集合
		List<MenuEx> menuExList = new ArrayList<MenuEx>();

		// 获取所有controller集合
		Map<String, Object> controllers = applicationContext.getBeansWithAnnotation(Controller.class);

		// 循环找出bodyPermissionsList，menuExList 集合并添加进去
		for (Object controller : controllers.values()) {
			Class<? extends Object> classs = controller.getClass();
			
			Method[] methods = classs.getMethods();
			
			for (Method method : methods) {
			
				RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
				if (requiresPermissions != null) {
					BodyPermissions bodyPermissions = method.getAnnotation(BodyPermissions.class);
					if (bodyPermissions != null) {
						bodyPermissionsList.add(bodyPermissions);
					} else {
						MenuEx menuEx = method.getAnnotation(MenuEx.class);
						if (menuEx != null) {
							menuExList.add(menuEx);
						}
					}
				}
			
			}//methods
		}
		
		//除去 权限相同的数据
		List<MenuEx> menuExList2 = new ArrayList<MenuEx>();
		for (MenuEx menuEx : menuExList) {
			
			if(menuExList2.size()==0) {
				menuExList2.add(menuEx);
			}else {
				boolean flag = true;
				for (MenuEx menuEx2 : menuExList2) {
					if(menuEx2.code() .equals(menuEx.code()) ) {
						flag = false;
					}
				}
				if(flag) {
					menuExList2.add(menuEx);
				}
			}
		}
		menuExList = menuExList2;
		
		
		//除去 权限相同的数据
		List<BodyPermissions> bodyPermissionsList2 = new ArrayList<BodyPermissions>();
		for (BodyPermissions bodyPermissions : bodyPermissionsList) {
			
			if(bodyPermissionsList2.size()==0) {
				bodyPermissionsList2.add(bodyPermissions);
			}else {
				boolean flag = true;
				for (BodyPermissions bodyPermissions2 : bodyPermissionsList2) {
					if(bodyPermissions2.code() .equals(bodyPermissions.code()) ) {
						flag = false;
					}
				}
				if(flag) {
					bodyPermissionsList2.add(bodyPermissions);
				}
			}
		}
		bodyPermissionsList = bodyPermissionsList2;
		
		
		List<MenuEx> menuExListCopy = new ArrayList<MenuEx>();
		List<Integer> number = new ArrayList<Integer>();
		int i = 0;
		String parentCd = "";
		OK:
		while(true) {
		boolean flag = false;	
		for (MenuEx menuEx : menuExList) {
			if(parentCd.equals(menuEx.parentCd())) {
				menuExListCopy.add(menuEx);
				i++;
				flag = true;
			}
		}
		if(!flag) {break OK;}
		number.add(i);
		parentCd = menuExListCopy.get(i-1).code();
		}
		
		
		
		
		
		
		//把一级菜单排在前面
/*		Collections.sort(menuExList, new Comparator<MenuEx>() {
			public int compare(MenuEx arg0, MenuEx arg1) {
				return arg0.parentCd().split(".").length - arg1.parentCd().split(".").length;
			}
		});*/
		
		//先保存菜单
		List<Menu> menuAll = menuMapper.findAll();
		int ii = 1;
		for (MenuEx menuEx : menuExList) {
			boolean flag = false;
			Menu new_menu = new Menu(null,menuEx.name(),menuEx.code(),menuEx.parentCd(),menuEx.listSort());
			for (int j = 0; j < number.size(); j++) {
				if(ii<=number.get(j)) {
					new_menu.setLevel(number.get(j));
					break;
				}
			}
			for (Menu menu : menuAll) {
				if(menu.getMenuCode().equals(menuEx.code())) {
					if(!menu.equals(new_menu)) {
						menuMapper.updateMenu(new_menu);
					}
					flag = true;
					menuAll.remove(menu);//删除当前已使用过的，提高效率，又可用于多余的数据清出
					break;
				}
			}
			if(!flag) {
				menuMapper.insertMenu(new_menu);
			}
			ii ++;
		}
		
		//删除多余的
		for (Menu menu : menuAll) {
			menuMapper.delMenu(menu);
		}
		
		//保存内容集合(权限)
		List<Permission> permissionAll = permissionMapper.findAll();
		for (MenuEx menuEx : menuExList) {
			boolean flag = false;
			Permission permission=new Permission();
			permission.setMenuCode(menuEx.code());
			permission.setPermissionName(menuEx.name());
			permission.setPermissionCode(menuEx.code());
			
			for (Permission lod_permission : permissionAll) {
				if(lod_permission.getPermissionCode().equals(permission.getPermissionCode())) {
					if(!permission.equals(lod_permission)) {
						permissionMapper.updatePermission(permission);
					}
					flag = true;
					permissionAll.remove(lod_permission);
					break;
				}
			}
			
			if(!flag) {
				permissionMapper.insertPermission(permission);
			}
		}
		
		for (BodyPermissions bodyPermissions : bodyPermissionsList) {
			boolean flag = false;
			Permission permission=new Permission();
			permission.setMenuCode(bodyPermissions.menuCode());
			permission.setPermissionName(bodyPermissions.name());
			permission.setPermissionCode(bodyPermissions.code());
			
			for (Permission lod_permission : permissionAll) {
				if(lod_permission.getPermissionCode().equals(permission.getPermissionCode())) {
					if(!permission.equals(lod_permission)) {
						permissionMapper.updatePermission(permission);
					}
					flag = true;
					permissionAll.remove(lod_permission);
					break;
				}
			}
			
			if(!flag) {
				permissionMapper.insertPermission(permission);
			}
		}

		//删除多余的
		for (Permission permission : permissionAll) {
			permissionMapper.delPermission(permission);
		}
		
	}
	
	
	
	/**************************************初始化菜单和权限--end**************************************/
	
	
	
	
	
	/************************************************授权manager start********************************************/
	
	@Autowired
	private RoleMapper roleMapper;
	
	/**
	 * 批量授权
	 * @param roleId 角色id
	 * @param permissionIds 权限id
	 */
	@Override 
	public void batchAuthorization(Integer roleId,Integer [] permissionIds) {
		ShiroUser currentUser = getCurrentUser();
		Date current = new Date();
		for (Integer integer : permissionIds) {
			roleMapper.insertRolePermission(integer, roleId, current, currentUser.getUserId());
		}
	}
	
	/**
	 * 批量删除授权
	 * @param roleId 角色id
	 * @param permissionIds 权限id
	 */
	@Override
	public void batchDelAuthorization(Integer roleId,Integer [] permissionIds) {
		ShiroUser currentUser = getCurrentUser();
		Date current = new Date();
		for (Integer integer : permissionIds) {
			roleMapper.removeRolePermission(roleId, integer, current, currentUser.getUserId());
		}
	}
	
	/**
	 * 给用户增加一组角色
	 * @param userId
	 * @param roleIds
	 */
	@Override
	public void addBatchUserRole(String userId,Integer [] roleIds) {
		ShiroUser currentUser = getCurrentUser();
		Date current = new Date();
		for (Integer integer : roleIds) {
			roleMapper.addUserRole(userId,integer,current,currentUser.getUserId());
		}
	}
	
	/**
	 * 给用户取消一组角色
	 * @param userId
	 * @param roleIds
	 */
	@Override
	public void removeBatchUserRole(String userId,Integer [] roleIds) {
		ShiroUser currentUser = getCurrentUser();
		for (Integer integer : roleIds) {
			roleMapper.removeUserRole(userId, currentUser.getUserId(), integer);
		}
	}
	
	/**
	 * 添加一个角色
	 */
	@Override
	public void addRole(String roleName) {
		ShiroUser currentUser = getCurrentUser();
		Date current = new Date();
		Role role = new Role();
		role.setCreateTime(current);
		role.setCreateUserId(currentUser.getUserId());
		role.setDeleted(0);
		role.setRoleName(roleName);
		role.setUpdateTime(current);
		role.setUpdateUserId(currentUser.getUserId());
		roleMapper.addRole(role);
	}
	
	@Override
	public void delRole(Integer roleId){
		ShiroUser currentUser = getCurrentUser();
		Date current = new Date();
		roleMapper.delRole(roleId, current, currentUser.getUserId());
	}
	/************************************************授权manager end********************************************/
	
	
	
	
	/************************************************权限相关查询start********************************************/
	
	/**
	 * 查询用户权限--相同权限将被合并为一个
	 * @param userId
	 * @return
	 */
	@Override
	public List<Permission> findPermissionByUser(String userId){
		//permissionMapper.delPermission(userId);
		return null;
	}
	
	/**
	 * 查询角色权限
	 * @param roleId
	 * @return
	 */
	@Override
	public List<Permission> findPermissionByRole(Integer roleId){
		List<Permission> permissions = permissionMapper.findPermissionByRole(roleId);
		return permissions == null ? new ArrayList<Permission>():permissions;
	}
	
	/**
	 * 查询全部权限
	 * @return
	 */
	@Override
	public List<Permission> findPermissionAll( ){
		return permissionMapper.findAll();
	}
	
	/**
	 * 查询全部角色
	 * @return
	 */
	@Override
	public List<Role> findRoleAll( ){
		List<Role> roleAll = roleMapper.findRoleAll();
		return roleAll == null ?new ArrayList<Role>():roleAll;
	}
	
	
	/************************************************权限相关查询end********************************************/
	
	/**
	 * 获取当前用户shirouser
	 * @return
	 */
	public static ShiroUser getCurrentUser() {
		Object attribute = SecurityUtils.getSubject().getSession().getAttribute(AuthRealm.CURRENT_USER);
		ShiroUser shiroUser =attribute != null ?(ShiroUser)attribute:null;
		return shiroUser;
	}
}
